package tenant

import (
	"cgs-server/server/assets/cgs_portal/category"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"cgs-server/server/system/role"
	"cgs-server/server/system/user"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
)

type TenantService interface {
	base.Service
	GetByTenantId(mdl *model.DataUserModel) (*Tenant, error) // 根据 tenantId 查询

	getTenantId([]string) string // 生成 TenantId
}

func NewTenantService() TenantService {
	tenantRepo := NewTenantRepository()
	return &tenantService{
		tenantRepo:  tenantRepo,
		ServiceImpl: base.ServiceImpl{Repo: tenantRepo},
	}
}

type tenantService struct {
	tenantRepo TenantRepository
	base.ServiceImpl
}

func (t *tenantService) Save(mdl *model.DataUserModel) error {
	if tenantVo, ok := mdl.Data.(*TenantVo); ok {

		// 1. 添加租户，租户名唯一
		tenants, err := t.tenantRepo.FindAll()
		if err != nil {
			return err
		}
		ids := make([]string, len(tenants))
		for idx := range tenants {
			ids[idx] = tenants[idx].TenantId
			/*if tenants[idx].TenantName == tenantVo.TenantName {
				return errors.New("tenant name is not allowed duplicated")
			}*/
		}
		// 设置 TenantId
		tenant := tenantVo.Tenant
		tenant.TenantId = t.getTenantId(ids)
		err = t.tenantRepo.Insert(&model.DataUserModel{
			Data: tenant,
			User: mdl.User,
		})
		if err != nil {
			return err
		}
		// 2. 添加角色
		// 2.1 添加管理员角色(需要设置租户id）
		sort := 0
		roleModel := &model.Role{
			RoleName:  "管理员",
			ParentId:  "0",
			Sort:      &sort,
			RoleAlias: "Administrator",
			TenantModel: model.TenantModel{
				TenantId: tenant.TenantId,
			},
			Type:      model.BackRole,
			IsInitial: tenantVo.IsInitial,
		}
		roleService := role.NewRoleService()
		err = roleService.Save(&model.DataUserModel{
			Data: roleModel,
			User: mdl.User,
		})
		if err != nil {
			return err
		}
		// 2.2 添加应用管理员角色
		roleModel2 := &model.Role{
			RoleName:  "应用管理员",
			ParentId:  "0",
			Sort:      &sort,
			RoleAlias: "AppAdministrator",
			TenantModel: model.TenantModel{
				TenantId: tenant.TenantId,
			},
			Type: model.BackRole,
		}
		err = roleService.Save(&model.DataUserModel{
			Data: roleModel2,
			User: mdl.User,
		})
		if err != nil {
			return err
		}
		// 2.3 添加普通用户角色，（默认添加的用户角色）
		roleModel3 := &model.Role{
			RoleName:  "普通用户",
			ParentId:  "0",
			Sort:      &sort,
			RoleAlias: "User",
			TenantModel: model.TenantModel{
				TenantId: tenant.TenantId,
			},
			Type: model.BackRole,
		}
		err = roleService.Save(&model.DataUserModel{
			Data: roleModel3,
			User: mdl.User,
		})
		if err != nil {
			return err
		}
		// 3. 添加用户(需要设置租户id和角色id)
		usr := tenantVo.User
		usr.TenantId = tenant.TenantId
		usr.RoleID = roleModel.Id.Hex()
		userService := user.NewUserService()
		err = userService.Save(&model.DataUserModel{
			Data: usr,
			User: mdl.User,
		})
		if err != nil {
			return err
		}

		// 4. 添加默认分类
		categoryModel := &category.Category{
			CategoryKey:   "分类1",
			CategoryValue: "0",
			VisualType:    "ThreeD",
		}
		categoryModel.TenantId = tenant.TenantId
		categoryService := category.NewCategoryService()
		err = categoryService.Save(&model.DataUserModel{
			Data: categoryModel,
			User: mdl.User,
		})
		return err
	} else {
		return errors.New("TenantVo type error")
	}
}

func (t *tenantService) List(mdl *model.DataUserModel) (interface{}, error) {
	result, err := t.tenantRepo.Find(mdl)
	if err != nil {
		return nil, err
	}

	res, ok := result.(*Tenants)
	if !ok {
		return nil, errors.New("tenant not found")
	}

	userRepo := user.NewUserRepository()
	roleRepo := role.NewRoleRepository()
	for _, tenant := range *res {
		filter := bson.M{
			"roleAlias": "Administrator",
			"type":      model.BackRole,
			"tenantId":  tenant.TenantId,
		}
		r, err := roleRepo.FindByRoleAliasOrName(&model.DataUserModel{
			Data:   &model.Role{},
			Filter: &filter,
		})
		if err != nil {
			return nil, err
		}
		filter = bson.M{
			"RoleID": r.GetId(),
		}
		one, err := userRepo.FindOne(&model.DataUserModel{
			Data:   &model.User{},
			Filter: &filter,
		})
		if err != nil {
			return nil, err
		}
		tenant.Admin = one.(*model.User)
	}

	return result, err
}

func (t *tenantService) GetOne(model *model.DataUserModel) (interface{}, error) {
	// TODO 这里还没写完
	result, err := t.tenantRepo.FindOne(model)
	return result, err
}

func (t *tenantService) GetByTenantId(mdl *model.DataUserModel) (*Tenant, error) {
	result, err := t.tenantRepo.FindOne(mdl)
	if err != nil {
		return nil, err
	}
	return result.(*Tenant), nil
}

func (t *tenantService) Update(mdl *model.DataUserModel) error {
	err := t.tenantRepo.Update(mdl)
	return err
}

func (t *tenantService) RemoveLogic(mdl *model.DataUserModel) error {
	if tenant, ok := mdl.Data.(*Tenant); ok {
		if tenant.TenantId == "000000" {
			return errors.New("Not allowed to delete the super tenant.")
		}
		err := t.tenantRepo.DeleteLogic(mdl)
		if err != nil {
			return err
		}
		// 删除下面的用户
		userService := user.NewUserService()
		err = userService.BatchRemoveUserByTenantId(tenant.TenantId, mdl.User)
		if err != nil {
			return err
		}
		// 删除账户信息
		infoService := NewTenantInfoService()
		err = infoService.RemoveLogicByTenantId(tenant.TenantId, mdl.User)
		return err
	} else {
		return model.NewTypeError("tenant")
	}
}

func (t *tenantService) getTenantId(ids []string) string {
	code := base.GenerateTenantId()
	if code == "000000" {
		// 不允许创建超级租户
		return t.getTenantId(ids)
	}
	for _, id := range ids {
		if code == id {
			return t.getTenantId(ids)
		}
	}
	return code
}
